package chapter01.part10;

import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 使用群组和分区 来简化收集成映射表
 * 
 * @author insight
 * @since 2021/7/21
 */
public class GroupBy {
    public static void main(String[] args) {
        Supplier<Stream<Locale>> locales = () -> Stream.of(
                Locale.getAvailableLocales()
        );

        // 指定特定函数 作为分类依据
        Map<String, List<Locale>> countryToLocales = locales.get().collect(
                Collectors.groupingBy(Locale::getCountry)
        );
        System.out.println(countryToLocales.get("IE"));
        
        // 还可以映射成其他表
        ConcurrentMap<String, List<Locale>> countryToLocalesCur = locales.get().collect(
                Collectors.groupingByConcurrent(Locale::getCountry));
        // 等价于
        ConcurrentMap<String, Set<String>> countryLangageNamesCur = locales.get().collect(
                Collectors.toConcurrentMap(
                        Locale::getDisplayCountry,
                        l -> Collections.singleton(l.getDisplayLanguage()),
                        (v, newV) -> {
                            HashSet<String> union = new HashSet<String>(v);
                            union.addAll(newV);
                            return union;
                        }
                ));
        
        // 如果分类函数是条件函数 那只有两类 符合和不符合
        // 这种情况使用 partitioningBy 更好
        Map<Boolean, List<Locale>> partitioningBy = locales.get().collect(
                Collectors.partitioningBy(
                        l -> "en".equals(l.getLanguage())
                )
        );
        System.out.println(partitioningBy.get(true));
    }
}